package com.wash.shoes.controller.mobile;


import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.request.BaseWxPayRequest;
import com.github.binarywang.wxpay.bean.request.WxPayRefundV3Request;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.result.BaseWxPayResult;
import com.github.binarywang.wxpay.bean.result.WxPayRefundV3Result;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import com.google.common.collect.Lists;
import com.google.zxing.Result;
import com.ruoyi.common.core.domain.R;
import com.wash.shoes.common.enums.OrderStatusEnum;
import com.wash.shoes.controller.mobile.test.WechatPayService;
import com.wash.shoes.domain.dto.MobileOrderDto;
import com.wash.shoes.domain.dto.MtUserAddress;
import com.wash.shoes.domain.jd.JdCreateOrder;
import com.wash.shoes.domain.order.PayNotifyOrderComponent;
import com.wash.shoes.entity.*;
import com.wash.shoes.exception.WashException;
import com.wash.shoes.service.*;
import com.wash.shoes.util.AddressCuttingUtil;
import com.wash.shoes.util.AesUtil;
import com.wash.shoes.util.WsRandomUtil;
import com.wechat.pay.java.core.util.PemUtil;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse;
import com.wechat.pay.java.service.refund.RefundService;
import com.wechat.pay.java.service.refund.model.AmountReq;
import com.wechat.pay.java.service.refund.model.CreateRequest;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.log4j.Log4j2;
import okhttp3.HttpUrl;
import org.apache.commons.io.IOUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.security.*;
import java.util.*;


@Api(tags = {"移动端-支付"})
@RestController
@RequestMapping({"/mobile-api/customer"})
public class WxPayMController extends BaseMController {

    private static final Logger log = LoggerFactory.getLogger("pay-record");

    @Autowired
    ShopService shopService;

    @Autowired
    WechatPayService wechatPayService;

    @Autowired
    OrderService orderService;

    @Autowired
    CustomerService customerService;

    @Autowired
    AesUtil aesUtil;

    @Autowired
    RefundService refundService;

    @Autowired
    PayNotifyOrderComponent payNotifyOrderComponent;

    @ApiOperation("微信支付回调")
    @ResponseBody
    @PostMapping("/payNotify")
    @Transactional
    public String payNotify(@RequestBody String xmlData) {
        try {
            log.info("payNotify xmlResult is {}", xmlData);

            JSONObject jsonObject = JSON.parseObject(xmlData);
            JSONObject resourceJson = jsonObject.getJSONObject("resource");
            String associated_data = resourceJson.getString("associated_data");
            String nonce = resourceJson.getString("nonce");
            String ciphertext = resourceJson.getString("ciphertext");
            String dataInfo = aesUtil.decryptToString(associated_data.getBytes(), nonce.getBytes(), ciphertext);
            log.info("dataInfo is {}", dataInfo);
            JSONObject dataInfoJsonObject = JSON.parseObject(dataInfo);
            String outTradeNo = dataInfoJsonObject.getString("out_trade_no");
            String tradeId = outTradeNo.split("_")[0];
            String transactionId = dataInfoJsonObject.getString("transaction_id");
            log.info("transactionId is {}  tradeId is {})", transactionId, tradeId);
            OrderPo orderPo = orderService.getById(tradeId);
            orderPo.setWxOutTradeNo(outTradeNo);
            orderPo.setWxTransactionId(transactionId);
            if (OrderStatusEnum.PRE_PAY.getStatus().equals(orderPo.getStatus())) {
                // 处理订单的回掉信息
                return payNotifyOrderComponent.process(orderPo);
            }else {
                log.error("订单的支付处理");
                return "";
            }
        } catch (Exception e) {
            log.error("微信回调结果异常,异常原因 {}", e);
            return WxPayNotifyResponse.fail(e.getMessage());
        }
    }


    @ApiOperation("微信退款回调")
    @ResponseBody
    @PostMapping("/wxpayOrderRefund")
    public String payRefundNotify(@RequestBody String xmlData) {
        try {
            log.info("微信退款回调 xmlResult is {}", xmlData);
            log.info("payRefundNotify xmlResult is {}", xmlData);

        } catch (Exception e) {
            log.error("微信回调结果异常,异常原因{}", e);
            return WxPayNotifyResponse.fail(e.getMessage());
        }
        return "success";
    }


    @ApiOperation("微信支付")
    @ResponseBody
    @GetMapping(value = "wxpayOrder")
    public R<PrepayWithRequestPaymentResponse> wxpayOrder(String orderId) {
        log.info("用户支付调用 orderId is {}", orderId);

        OrderPo orderPo = orderService.getById(orderId);
        if (orderPo.getStatus() != OrderStatusEnum.PRE_PAY.getStatus()) {
            throw new WashException("订单的状态不正确,不能支持该订单");
        }
        CustomerPo customerPo = customerService.getById(orderPo.getCustomId());
        String payOrder = orderId + "_" + WsRandomUtil.generateByRandom(10);
        log.info("payOrder is {}", payOrder);
        PrepayWithRequestPaymentResponse prepayWithRequestPaymentResponse = wechatPayService.prepayWithRequestPayment("用户购买商品", payOrder, BigDecimal.valueOf(orderPo.getTotalPrice()), customerPo.getOpenId());
        return R.ok(prepayWithRequestPaymentResponse);
    }

    @ApiOperation("微信支付")
    @ResponseBody
    @GetMapping(value = "wxpayOrderRefund")
    public R<String> GetMapping(String orderId) throws WxPayException, IOException, SignatureException, NoSuchAlgorithmException, InvalidKeyException {

        CreateRequest request = new CreateRequest();
        //设置退款金额 根据自己的实际业务自行填写
        AmountReq amountReq = new AmountReq();
        amountReq.setRefund(1L);
        amountReq.setTotal(1L);
        amountReq.setCurrency("CNY");
        request.setAmount(amountReq);
        //支付成功后回调回来的transactionId 按照实际情况填写
        request.setTransactionId("4200002523202412085768542842");
        request.setOutTradeNo("202412083719473388_18p8u972Af");
        //支付成功后回调回来的transactionId 按照实际情况填写
        request.setOutRefundNo("transactionId");
        //退款成功的回调地址
        request.setNotifyUrl("https://www.shoeswasher.com/mobile-api/customer/wxpayOrderRefund/");
        //发起请求,申请退款
        com.wechat.pay.java.service.refund.model.Refund refund = refundService.create(request);
        //调用成功的响应数据
        System.out.println(refund);
        return R.ok(JSON.toJSONString(refund));
    }

}
